// From Thinking in C++, 2nd
Edition
// Available at
http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in
Copyright.txt
//:
C03:AllDefinitions.cpp
// All
possible combinations of basic data types,
// specifiers,
pointers and references
#include
<iostream>
using
namespace std;
#define P(STR,X) cout << STR << " " <<
#X << " = " << X << endl;
void
f1(char c, int i, float f, double d);
void
f2(short int si, long int li, long double ld);
void
f3(unsigned char uc, unsigned int ui, unsigned short int usi, unsigned long int
uli);
void
f4(char* cp, int* ip, float* fp, double* dp);
void
f5(short int* sip, long int* lip, long
double* ldp);
void f6(unsigned char* ucp, unsigned int* uip,
unsigned short int* usip, unsigned long int* ulip);
void
f7(char& cr, int& ir, float& fr, double& dr);
void
f8(short int& sir, long int& lir,long double& ldr);
void
f9(unsigned char& ucr, unsigned int& uir,unsigned
short
int& usir,unsigned long int&ulir);
void
main() {
f1('A',10,2.5,34.0);
f2(2,10000,34.0678);
f3('B',2,160,234
);
char c = 'L';
char * cp =
&c;
int a = 1;
int *ap=&a;
float f =2.5 ;
float *fp= &f;
double d = 0.9000;
double *dp=
&d;
f4( cp, ap, fp,
dp);
short int si = 10;
long int li =1000;
long double ldb = 2.0009;
f5( &si , &li , &ldb);
unsigned char uc =
56;
unsigned int ui =
45;
unsigned short int
usi = 127;
unsigned long int
uli = 20000;
f6(&uc,&ui,
&usi, &uli);
f7(c, a, f, d);
f8(si ,li, ldb);
f9(uc, ui, usi, uli);
} ///:~
void
f1(char c, int i, float f, double d)
{
P("char",c);
P("int",i);
P("float",f);
P("double",d);
}
void f2(short
int si, long int li, long double ld)
{
P("short
int",si);
P("long
int",li);
P("long
double",ld);
}
void
f3(unsigned char uc, unsigned int ui,unsigned short int usi, unsigned long int
uli)
{
P("unsigned
char",uc);
P("unsigned int",ui);
P("unsigned
short int",usi);
P("unsigned
long int",uli);
}
void
f4(char* cp, int* ip, float* fp, double* dp)
{
P("char*",cp);
P("int*",ip);
P("float*",fp);
P("double*",dp);
}
void
f5(short int* sip, long int* lip, long double* ldp)
{
P("short
int*",sip);
P("long
int*",lip);
P("long
double*",ldp);
}
void
f6(unsigned char* ucp, unsigned int* uip, unsigned short int* usip,
unsigned long int*
ulip)
{
P("unsigned
char*",ucp);
P("unsigned
int*",uip);
P("unsigned
short int*",usip);
P("unsigned
long int*",ulip);
}
void
f7(char& cr, int& ir, float& fr, double& dr)
{
P("char&",cr);
P("int&",ir);
P("float&",fr);
P("double&",dr);
}
void f8(short
int& sir, long int& lir, long double& ldr)
{
P("short
int&",sir);
P("long
int&",lir);
P("long
doubl&",ldr);
}
void
f9(unsigned char& ucr, unsigned int& uir,unsigned short int& usir,
unsigned long
int& ulir)
{
P("unsigned
char&",ucr);
P("unsigned
int&",uir);
P("unsigned
short int&",usir);
P("unsigned
long int&",ulir);
}
//:
C03:ArgsToInts.cpp
// Converting command-line arguments to ints
#include
<iostream>
#include
<cstdlib>
using namespace
std;
void
main(int argc, char* argv[]) {
for(int i = 0; i < argc; i++)
cout << atoi(argv[i]) << endl;
} ///:~
#include
<iostream>
using
namespace std;
int
main(int argc, char* argv[]) {
cout <<
"argc = " << argc << endl;
for(int i = 0; i < argc; i++)
cout << "argv[" << i << "] = "
<< argv[i] << endl;
} ///:~
//:
C03:ArrayAddresses.cpp
// From
Thinking in C++, 2nd Edition
//
Available at http://www.BruceEckel.com
// (c)
Bruce Eckel 2000
//
Copyright notice in Copyright.txt
#include
<iostream>
using
namespace std;
void
main() {
int a[10];
long l[10];
double d[10];
cout <<
"sizeof(int) = "<< sizeof(int) << endl;
cout <<
"sizeof(long) = "<< sizeof(long) << endl;
cout <<
"sizeof(float) = "<< sizeof(float) << endl;
for(int i = 0; i
< 10; i++)
{
cout <<
"&a[" << i << "] = " << (long)&a[i] << endl;
cout <<
"&d[" << i << "] = " << (long)&d[i] << endl;
cout <<
"&l[" << i << "] = " << (long)&l[i] << endl;
}
}
#include
<iostream>
#include
<string>
using
namespace std;
void
func1(int a[], int size) {
for(int i = 0; i
< size; i++)
a[i] = i * i - i;
}
void
func2(int* a, int size) {
for(int i = 0; i <
size; i++)
a[i] = i * i + i;
}
void
print(int a[], string name, int size) {
for(int i = 0; i
< size; i++)
cout << name
<< "[" << i << "] = "
<< a[i]
<< endl;
}
void
main() {
int a[5], b[5];
// Probably garbage
values:
print(a,
"a", 5);
print(b,
"b", 5);
// Initialize the arrays:
func1(a, 5);
func1(b, 5);
print(a,
"a", 5);
print(b,
"b", 5);
// Notice the arrays are always modified:
func2(a, 5);
func2(b, 5);
print(a,
"a", 5);
print(b,
"b", 5);
} ///:~
#include
<iostream>
using
namespace std;
void
main() {
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int *ap = a;
cout <<
"a = " << a << endl;
cout <<
"&a[0] =" << &a[0] << endl;
cout << *ap
<< endl;
cout << ap[3]
<< endl;
ap = a;
cout << *ap
<< endl;
cout <<
"&a[1] =" << &a[1] << endl;
cout << "
a[1] =" << a[1] <<
endl;
for(int i=0;
i<10;i++)
{
cout <<
ap[i] << endl;
cout <<
*(ap+i) << endl;
cout <<
i[ap] << endl;
}
for( i=0;
i<10;i++)
{
cout <<
&ap[i] << endl;
cout <<
(ap+i) << endl;
}
} ///:~
#include
<iostream>
using
namespace std;
void
main() {
int a[10];
for(int i = 0; i
< 10; i++) {
a[i] = i * 10;
cout <<
"a[" << i << "] = " << a[i] <<
endl;
cout <<
"&a[" << i << "] = " << &a[i]
<< endl;
}
} ///:~
// Use of
the assert() debugging macro
#include
<cassert> //
Contains the macro
void
main() {
int i = 100;
int a = 2;
assert(i != 100); //
Fails
assert (a ==3);
} ///:~
// Shows
use of auto-increment
// and
auto-decrement operators.
#include
<iostream>
using
namespace std;
#define P(STR,VAR) cout << STR << " = "
<< VAR << endl;
void main() {
int i = 0;
int j = 0;
P("i",i);
P("j",j);
P("++i", ++i); // Pre-increment
P("--i",
--i); // Pre-decrement
P("j++",j++); // Post-increment
P("j--",j--); // Post decrement
} ///:~
//{L}
printBinary
//
Demonstration of bit manipulation
#include
<iostream>
#include
<iomanip>
#include
"iodos.h"
using
namespace std;
void
printBinary(const unsigned char val);
// A macro
to save typing:
#define PR(STR, EXPR) \
cout <<
STR;cout << setw(10); printBinary(EXPR); cout << endl;
void
main() {
dos_console();
unsigned int getval;
unsigned char
a, b;
cout << "Skriv två tal mellan 0 och 255: ";
cin >> getval; a = getval;
cin >> getval;
b = getval;
PR("a
binärt: ", a);
PR("b
binärt: ", b);
PR("a | b
= ", a | b);
PR("a & b
= ", a & b);
PR("a ^ b
= ", a ^ b);
PR("~a = ", ~a);
PR("~b = ", ~b);
cout <<
"Ett intressant mönster" << endl;
cout <<
"c = 0x5A " << endl;
// An interesting
bit pattern:
unsigned char c =
0x5A;
PR("c in
binary: ", c);
a |= c;
PR("a |= c; a
= ", a);
b &= c;
PR("b &= c;
b = ", b);
b ^= a;
PR("b ^= a; b
= ", b);
} ///:~
#include
<iostream>
void printBinary(const
unsigned char val) {
for(int i = 7; i
>= 0; i--)
if(val & (1
<< i))
std::cout << "1";
else
std::cout << "0";
} ///:~
//
Relational and logical operators.
#include
<iostream>
using
namespace std;
void
main() {
int i,j;
cout << "Enter an integer: ";
cin >> i;
cout << "Enter another integer: ";
cin >> j;
cout <<
"i > j is " << (i > j) << endl;
cout <<
"i < j is " << (i < j) << endl;
cout <<
"i >= j is " << (i >= j) << endl;
cout <<
"i <= j is " << (i <= j) << endl;
cout <<
"i == j is " << (i == j) << endl;
cout <<
"i != j is " << (i != j) << endl;
cout <<
"i && j is " << (i && j) << endl;
cout <<
"i || j is " << (i || j) << endl;
cout << "
(i < 10) && (j < 10) is "
<< ((i < 10) && (j < 10)) << endl;
} ///:~
#include
<iostream>
#include
"iodos.h"
#include
<iomanip>
using
namespace std;
#define PR(STR, VAR) cout << STR <<" " << VAR << endl;
void
main() {
int i = 99;
PR("int i =
",i);
void* vp = &i;
// Can't dereference
a void pointer:
// *vp = 3; //
Compile-time error
// Must cast back to int before
dereferencing:
*((int*)vp) = 3;
PR("int i = ",i);
double a = 2.45;
void *ap = &a;
PR("double a =
",a);
*((double*)ap)=5.5;
PR("double a
= ",a);
} ///:~
// Simple
demonstration of recursion
#include
<iostream>
using
namespace std;
void
removeHat(char cat) {
for(char c = 'A'; c
< cat; c++)
cout <<
" ";
if(cat <= 'Z') {
cout <<
"cat " << cat << endl;
removeHat(cat +
1); // Recursive call
} else
cout <<
"VOOM!!!" << endl;
}
void
main() {
removeHat('A');
} ///:~
// Display all the ASCII characters
//
Demonstrates "for"
#include
<iostream>
using
namespace std;
void
main() {
for(int i = 0; i
< 128; i = i + 1)
if (i != 26) // ANSI Terminal Clear screen
cout <<
" value: " << i
<< "
character: "
<< char(i)
// Type conversion
<< endl;
} ///:~
//UNDVIK
HELST
#include
<iostream>
using
namespace std;
void
main() {
int a = 0, b = 1, c
= 2, d = 3, e = 4;
a = (b++, c++, d++, e++);//endast det sista räknas ut a blir öika med 4
cout << "a = " << a << endl; //försök undvika comma operator
// The parentheses are
critical here. Without
// them, the
statement will evaluate to:
(a = b++), c++, d++, e++;
cout <<
"a = " << a << endl;
} ///:~
/*Walk
through each one and use the right-left guideline to figure it out.
Number 1 says fp1 is a pointer
to a function that takes an integer
argument
and returns a pointer to an array of 10 void pointers.*/
/* 1.
*/ void * (*(*fp1)(int))[10];
/*Number 2 says fp2 is a pointer
to a function that takes three arguments
(int, int, and float) and returns a pointer to a function
that takes an
integer
argument and returns a float.*/
/* 2.
*/ float (*(*fp2)(int,int,float))(int);
/*If you
are creating a lot of complicated definitions, you might want to
use a
typedef. Number 3 shows how a typedef saves typing the complicated
description
every time. It says An
fp3 is a pointer to a function that
takes no
arguments and returns a pointer to an array of 10 pointers to
functions
that take no arguments and return doubles. Then it says a
is one of
these fp3 types. typedef
is generally useful for building
complicated
descriptions from simple ones.*/
/* 3.
*/ typedef double (*(*(*fp3)())[10])();
fp3 a;
/*Number 4
is a function declaration instead of a variable definition.
It says f4
is a function that returns a pointer to an array of
10 pointers
to functions that return integers.*/
/* 4.
*/ int (*(*f4())[10])();
void
main() {} ///:~
/*const_cast
If you want
to convert from a const to a nonconst or from a
volatile
to a nonvolatile, you use const_cast. This is the only
conversion
allowed with const_cast; if any other conversion is involved
it must be
done using a separate expression or you’ll get a compile-time
error.*/
void
main() {
const int i = 0;
const int b =0;
int* j =
(int*)&i; // Deprecated form
j = const_cast<int*>(&i); //
Preferred
// Can't do
simultaneous additional casting:
//! long* l = const_cast<long*>(&i); // Error
volatile int k = 0;
int* u =
const_cast<int*>(&k);
} ///:~
#include
<iostream>
#include
<string>
using
namespace std;
// Debug
flags aren't necessarily global:
bool debug
= false;
void
main(int argc, char* argv[]) {
for(int i = 0; i < argc; i++)
if(string(argv[i]) == "--debug=on")
debug = true;
bool go = true;
while(go) {
if(debug) {
// Debugging
code here
cout <<
"Debugger is now on!" << endl;
} else {
cout <<
"Debugger is now off." << endl;
}
cout <<
"Turn debugger [on/off/quit]: ";
string reply;
cin >>
reply;
if(reply ==
"on") debug = true; // Turn it on
if(reply ==
"off") debug = false; // Off
if(reply == "quit") break; // Out of 'while'
}
} ///:~
// Keeping
track of shapes
#include
<iostream>
using
namespace std;
enum
ShapeType {
circle,
square,
rectangle
}; // Must end with a
semicolon like a struct
void main()
{
ShapeType shape = circle;
// Activities here....
// Now do something based on what the shape
is:
shape = rectangle;
switch(shape) {
case circle: cout << "circle" <<
endl; break;
case square: cout
<< " square" << endl;break;
case
rectangle: cout <<
"rectangle" << endl; break;
}
} ///:~
// File
scope demonstration. Compiling and
// linking
this file with FileStatic2.cpp
// will
cause a linker error
// File
scope means only available in this file:
static
int fs;
int
main() {
fs = 1;
} ///:~
// Trying to reference fs
extern
int fs;
void
func() {
fs = 100;
} ///:~
//{L}
printBinary
//{T}
3.14159
#include
"printBinary.h"
#include
<cstdlib>
#include
<iostream>
using
namespace std;
void
main(int argc, char* argv[]) {
if(argc != 2) {
cout <<
"Must provide a number" << endl;
exit(1);
}
double d =
atof(argv[1]);
unsigned char* cp =
reinterpret_cast<unsigned char*>(&d);
for(int i =
sizeof(double)-1; i >= 0 ; i -= 2){
printBinary(cp[i-1]);
printBinary(cp[i]);
}
} ///:~
// Forward
function & data declarations
#include
<iostream>
using
namespace std;
// This is not actually external, but the
// compiler
must be told it exists somewhere:
extern int i;
extern void func();
void
main() {
i = 0;
func();
}
int i; //
The data definition
void
func() {
i++;
cout << i;
} ///:~
int
main() {
float a =
float(200);
// This is
equivalent to:
float b =
(float)200;
}
///:~
// Using an array of pointers to functions
#include
<iostream>
using
namespace std;
// A macro
to define dummy functions:
#define DF(N) void N() { \
cout <<
"function " #N " called..." << endl; }
DF(a);
DF(b); DF(c); DF(d); DF(e); DF(f); DF(g);
void
(*func_table[])() = { a, b, c, d, e, f, g };
int
main() {
while(1) {
cout <<
"press a key from 'a' to 'g' "
"or q to
quit" << endl;
char c, cr;
cin.get(c); cin.get(cr);
// second one for CR
if ( c == 'q' )
break; // ...
out of while(1)
if ( c < 'a' ||
c > 'g' )
continue;
(*func_table[c - 'a'])();
}
} ///:~
#include
<iostream.h>
int
addition (int a, int b)
{ return
(a+b); }
int
subtraction (int a, int b)
{ return
(a-b); }
int
(*minus)(int,int) = subtraction;
int
operation (int x, int y, int (*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
//avreferering
cout <<
functocall(x,y); //samma sak
return (g);
}
int main
()
{
int m,n;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n;
return 0;
}
//! visar hur funktioner kan användas som parametrar
//funktionen måste ha samma parameterar
#include <iostream>
#include
<iomanip>
using namespace std;
// funktion som dubblerar ett tal
int dubblera (int Tal) {
return Tal + Tal;
}
// funktion som kvadrerar att tal
int kvadrera (int Tal) {
return Tal * Tal;
}
// funktion som applicerar en given funktion på en serie med tal
void applicera (int (*funktion)(int) ) {
// iterera över talen 0 till 4
for
(int Index = 0; Index <= 4; Index++ ) {
// applicera den givna funktionen på talet
cout << "Tal: " << setw(3) << Index << " blir: "
<< setw(4) << funktion(Index) << endl;
}
int b= (*funktion)(3); //avreferera
cout << b << endl;
b= funktion(4); //samma som det här
cout << b << endl;
}
void main () {
cout << "Funktion: dubblera" << endl;
// anropa applicera() med funktionen dubblera()
applicera ( dubblera);
cout << endl << "Funktion: kvadrera" << endl;
// anropa applicera() med funktionen kvadrera()
applicera
( kvadrera );
}
//{L} Global2
//
Demonstration of global variables
#include
<iostream>
using
namespace std;
int
globe;
void
func();
int
main() {
globe = 12;
cout << globe
<< endl;
func(); // Modifies
globe
cout << globe
<< endl;
} ///:~
// Accessing external global variables
extern
int globe;
// (The
linker resolves the reference)
void
func() {
globe = 47;
} ///:~
// The infamous goto is supported in C++
#include
<iostream>
using
namespace std;
int
main() {
long val = 0;
for(int i = 1; i
< 1000; i++) {
for(int j = 1; j
< 100; j += 10) {
val = i * j;
if(val >
47000)
goto bottom;
// Break would only go to the outer
'for'
}
}
bottom: // A label
cout << val
<< endl;
} ///:~
// Guess a
number (demonstrates "while")
#include
<iostream>
using
namespace std;
int
main() {
int secret = 15;
int guess = 0;
// "!=" is
the "not-equal" conditional:
while(guess !=
secret) { // Compound statement
cout <<
"guess the number: ";
cin >>
guess;
}
cout <<
"You guessed it!" << endl;
} ///:~
// The guess program using do-while
#include
<iostream>
using
namespace std;
int
main() {
int secret = 15;
int guess; // No initialization
needed here
do {
cout <<
"guess the number: ";
cin >>
guess; // Initialization happens
} while(guess != secret);
cout <<
"You got it!" << endl;
} ///:~
//
Mathematical operators
#include
<iostream>
using
namespace std;
// A macro
to display a string and a value.
#define PRINT(STR, VAR) \
cout << STR " = " << VAR << endl
int
main() {
int i, j, k;
float u, v, w; // Applies to doubles, too
cout <<
"enter an integer: ";
cin >> j;
cout <<
"enter another integer: ";
cin >> k;
PRINT("j",j); PRINT("k",k);
i = j + k; PRINT("j
+ k",i);
i = j - k; PRINT("j - k",i);
i = k / j; PRINT("k / j",i);
i = k * j; PRINT("k * j",i);
i = k % j; PRINT("k % j",i);
// The following only
works with integers:
j %= k; PRINT("j %= k", j);
cout << "Enter a floating-point number:
";
cin >> v;
cout <<
"Enter another floating-point number:";
cin >> w;
PRINT("v",v);
PRINT("w",w);
u = v + w; PRINT("v + w", u);
u = v - w; PRINT("v - w", u);
u = v * w; PRINT("v * w", u);
u = v / w; PRINT("v / w", u);
// The following works for ints, chars,
// and doubles too:
PRINT("u", u); PRINT("v", v);
u += v; PRINT("u += v", u);
u -= v; PRINT("u -= v", u);
u *= v; PRINT("u *= v", u);
u /= v; PRINT("u /= v", u);
} ///:~
// Simple
menu program demonstrating
// the use
of "break" and "continue"
#include
<iostream>
using
namespace std;
int
main() {
char c; // To hold
response
while(true) {
cout <<
"MAIN MENU:" << endl;
cout <<
"l: left, r: right, q: quit -> ";
cin >> c;
if(c == 'q')
break; // Out of
"while(1)"
if(c == 'l') {
cout <<
"LEFT MENU:" << endl;
cout <<
"select a or b: ";
cin >> c;
if(c == 'a') {
cout <<
"you chose 'a'" << endl;
continue; //
Back to main menu
}
if(c == 'b') {
cout <<
"you chose 'b'" << endl;
continue; //
Back to main menu
}
else {
cout <<
"you didn't choose a or b!"
<< endl;
continue; //
Back to main menu
}
}
if(c == 'r') {
cout <<
"RIGHT MENU:" << endl;
cout <<
"select c or d: ";
cin >> c;
if(c == 'c') {
cout <<
"you chose 'c'" << endl;
continue; //
Back to main menu
}
if(c == 'd') {
cout <<
"you chose 'd'" << endl;
continue; //
Back to main menu
}
else {
cout <<
"you didn't choose c or d!"
<< endl;
continue; //
Back to main menu
}
}
cout <<
"you must type l or r or q!" << endl;
}
cout <<
"quitting menu..." << endl;
} ///:~
// A menu
using a switch statement
#include
<iostream>
using
namespace std;
int
main() {
bool quit =
false; // Flag for quitting
while(quit == false)
{
cout <<
"Select a, b, c or q to quit: ";
char response;
cin >>
response;
switch(response) {
case 'a' : cout
<< "you chose 'a'" << endl;
break;
case 'b' : cout
<< "you chose 'b'" << endl;
break;
case 'c' : cout
<< "you chose 'c'" << endl;
break;
case 'q' : cout
<< "quitting menu" << endl;
quit
= true;
break;
default : cout << "Please use a,b,c
or q!"
<< endl;
}
}
} ///:~
//
On-the-fly variable definitions
#include
<iostream>
using
namespace std;
int
main() {
//..
{ // Begin a new
scope
int q = 0; // C
requires definitions here
//..
// Define at point
of use:
for(int i = 0; i
< 100; i++) {
q++; // q comes
from a larger scope
// Definition at the end of the scope:
int p = 12;
}
int p = 1; // A different p
} // End scope containing q & outer p
cout <<
"Type characters:" << endl;
while(char c =
cin.get() != 'q') {
cout << c
<< " wasn't it" << endl;
if(char x = c ==
'a' || c == 'b')
cout <<
"You typed a or b" << endl;
else
cout <<
"You typed " << x << endl;
}
cout <<
"Type A, B, or C" << endl;
switch(int i =
cin.get()) {
case 'A': cout
<< "Snap" << endl; break;
case 'B': cout
<< "Crackle" << endl; break;
case 'C': cout
<< "Pop" << endl; break;
default: cout
<< "Not A, B or C!" << endl;
}
} ///:~
#include
<iostream>
using
namespace std;
void
f(int* p) {
cout <<
"p = " << p << endl;
cout <<
"*p = " << *p << endl;
*p = 5;
cout <<
"p = " << p << endl;
}
int
main() {
int x = 47;
cout <<
"x = " << x << endl;
cout <<
"&x = " << &x << endl;
f(&x);
cout <<
"x = " << x << endl;
} ///:~
#include
<iostream>
using
namespace std;
void
f(int a) {
cout <<
"a = " << a << endl;
a = 5;
cout <<
"a = " << a << endl;
}
int
main() {
int x = 47;
cout << "x = " << x << endl;
f(x);
cout <<
"x = " << x << endl;
} ///:~
#include
<iostream>
using
namespace std;
void
f(int& r) {
cout <<
"r = " << r << endl;
cout <<
"&r = " << &r << endl;
r = 5;
cout <<
"r = " << r << endl;
}
int
main() {
int x = 47;
cout <<
"x = " << x << endl;
cout <<
"&x = " << &x << endl;
f(x); // Looks like
pass-by-value,
// is actually pass by reference
cout <<
"x = " << x << endl;
} ///:~
// Operator
mistakes
#include
<iostream>
using
namespace std;
void
main() {
int a = 1, b = 1;
while(a =b) {
// ....
}
} ///:~
#include
<iostream>
using
namespace std;
#define P(EX) cout << #EX << ": " << EX
<< endl;
int
main() {
int a[10];
for(int i = 0; i
< 10; i++)
a[i] = i; // Give
it index values
int* ip = a;
P(*ip);
P(*++ip);
P(*(ip + 5));
int* ip2 = ip + 5;
P(*ip2);
P(*(ip2 - 4));
P(*--ip2);
P(ip2 - ip); //
Yields number of elements
} ///:~
#include
<iostream>
using
namespace std;
typedef
struct {
char c;
short s;
int i;
long l;
float f;
double d;
long double ld;
}
Primitives;
int
main() {
Primitives p[10];
Primitives* pp = p;
cout <<
"sizeof(Primitives) = "
<< sizeof(Primitives)
<< endl;
cout <<
"pp = " << (long)pp << endl;
pp++;
cout <<
"pp = " << (long)pp << endl;
} ///:~
#include
<iostream>
using
namespace std;
int
main() {
int i[10];
double d[10];
int* ip = i;
double* dp = d;
cout <<
"ip = " << (long)ip << endl;
ip++;
cout <<
"ip = " << (long)ip << endl;
cout <<
"dp = " << (long)dp << endl;
dp++;
cout <<
"dp = " << (long)dp << endl;
} ///:~
int
main() {
int a[10];
int* ip = a;
for(int i = 0; i < 10; i++)
ip[i] = i * 10;
} ///:~
// Defining and using a pointer to a function
#include
<iostream>
using
namespace std;
void
func() {
cout <<
"func() called..." << endl;
}
int
main() {
void (*fp)(); // Define a function pointer
fp = func; // Initialize it
(*fp)();
// Dereferencing calls the function
void (*fp2)() =
func; // Define and initialize
(*fp2)();
} ///:~
#include
<iostream>
// Display
a byte in binary
void
printBinary(const unsigned char val);
void
printBinary(const unsigned char val) {
for(int i = 7; i
>= 0; i--)
if(val & (1
<< i))
std::cout << "1";
else
std::cout << "0";
} ///:~
#include
<iostream>
using
namespace std;
const int
sz = 100;
struct X
{ int a[sz]; };
void
print(X* x) {
for(int i = 0; i
< sz; i++)
cout <<
x->a[i] << ' ';
cout << endl
<< "--------------------" << endl;
}
int
main() {
X x;
print(&x);
int* xp =
reinterpret_cast<int*>(&x);
for(int* i = xp; i < xp + sz; i++)
*i = 0;
// Can't use xp as an
X* at this point
// unless you cast it back:
print(reinterpret_cast<X*>(xp));
// In this example,
you can also just use
// the original identifier:
print(&x);
} ///:~
// Use of
"return"
#include
<iostream>
using
namespace std;
char
cfunc(int i) {
if(i == 0)
return 'a';
if(i == 1)
return 'g';
if(i == 5)
return 'z';
return 'c';
}
void
main() {
cout <<
"type an integer: ";
int val;
cin >> val;
cout << cfunc(val) << endl;
} ///:~
// Perform left and right rotations
unsigned
char rol(unsigned char val) {
int highbit;
if(val & 0x80)
// 0x80 is the high bit only
highbit = 1;
else
highbit = 0;
// Left shift (bottom bit becomes 0):
val <<= 1;
// Rotate the high
bit onto the bottom:
val |= highbit;
return val;
}
unsigned
char ror(unsigned char val) {
int lowbit;
if(val & 1) //
Check the low bit
lowbit = 1;
else
lowbit = 0;
val >>= 1; //
Right shift by one position
// Rotate the low
bit onto the top:
val |= (lowbit
<< 7);
return val;
} ///:~
// How variables
are scoped
int
main() {
int scp1;
// scp1 visible here
{
// scp1 still visible here
//.....
int scp2;
// scp2 visible here
//.....
{
// scp1 & scp2 still visible here
//..
int scp3;
// scp1, scp2 & scp3 visible here
// ...
} // <-- scp3 destroyed here
// scp3 not available here
// scp1 & scp2 still visible here
// ...
} // <-- scp2 destroyed here
// scp3 & scp2 not available here
// scp1 still visible here
//..
} // <--
scp1 destroyed here
///:~
// Allowing a struct to refer to itself
typedef
struct SelfReferential {
int i;
SelfReferential* sr; // Head spinning yet?
}
SelfReferential;
int
main() {
SelfReferential sr1, sr2;
sr1.sr = &sr2;
sr2.sr = &sr1;
sr1.i = 47;
sr2.i = 1024;
} ///:~
int
main() {
int b = 200;
unsigned long a =
(unsigned long int)b;
} ///:~
struct
Structure1 {
char c;
int i;
float f;
double d;
};
int
main() {
struct Structure1
s1, s2;
s1.c = 'a'; // Select an element using a '.'
s1.i = 1;
s1.f = 3.14;
s1.d = 0.00093;
s2.c = 'a';
s2.i = 1;
s2.f = 3.14;
s2.d = 0.00093;
} ///:~
// Using typedef with struct
typedef
struct {
char c;
int i;
float f;
double d;
}
Structure2;
int
main() {
Structure2 s1, s2;
s1.c = 'a';
s1.i = 1;
s1.f = 3.14;
s1.d = 0.00093;
s2.c = 'a';
s2.i = 1;
s2.f = 3.14;
s2.d = 0.00093;
} ///:~
// Using pointers to structs
typedef
struct Structure3 {
char c;
int i;
float f;
double d;
}
Structure3;
int
main() {
Structure3 s1, s2;
Structure3* sp = &s1;
sp->c = 'a';
sp->i = 1;
sp->f = 3.14;
sp->d = 0.00093;
sp = &s2; //
Point to a different struct object
sp->c = 'a';
sp->i = 1;
sp->f = 3.14;
sp->d = 0.00093;
} ///:~
// Demonstrates the use of specifiers
#include
<iostream>
using
namespace std;
int
main() {
char c;
unsigned char cu;
int i;
unsigned int iu;
short int is;
short iis; // Same
as short int
unsigned short int
isu;
unsigned short iisu;
long int il;
long iil; // Same as long int
unsigned long int
ilu;
unsigned long iilu;
float f;
double d;
long double ld;
cout
<< "\n char= " <<
sizeof(c)
<< "\n unsigned char = "
<< sizeof(cu)
<< "\n int = " << sizeof(i)
<< "\n unsigned int = "
<< sizeof(iu)
<< "\n short = " << sizeof(is)
<< "\n unsigned short = "
<< sizeof(isu)
<< "\n long = " << sizeof(il)
<< "\n unsigned long = "
<< sizeof(ilu)
<< "\n float = " << sizeof(f)
<< "\n double = " << sizeof(d)
<< "\n long double = "
<< sizeof(ld)
<< endl;
} ///:~
// Using a static variable in a function
#include
<iostream>
using
namespace std;
void
func() {
static int i = 0;
cout <<
"i = " << ++i << endl;
}
int
main() {
for(int x = 0; x
< 10; x++)
func();
} ///:~
void
func(int) {}
int
main() {
int i = 0x7fff; //
Max pos value = 32767
long l;
float f;
// (1) Typical castless conversions:
l = i;
f = i;
// Also works:
l = static_cast<long>(i);
f = static_cast<float>(i);
// (2) Narrowing conversions:
i = l; // May lose digits
i = f; // May lose info
// Says "I
know," eliminates warnings:
i = static_cast<int>(l);
i = static_cast<int>(f);
char c =
static_cast<char>(i);
// (3) Forcing a conversion from void* :
void* vp = &i;
// Old way produces a dangerous conversion:
float* fp =
(float*)vp;
// The new way is
equally dangerous:
fp =
static_cast<float*>(vp);
// (4) Implicit type conversions, normally
// performed by the compiler:
double d = 0.0;
int x = d; //
Automatic type conversion
x = static_cast<int>(d);
// More explicit
func(d); //
Automatic type conversion
func(static_cast<int>(d));
// More explicit
} ///:~
#include
<iostream>
using
namespace std;
#define P(A) cout << #A << ": " << (A)
<< endl;
int
main() {
int a = 1, b = 2, c
= 3;
P(a); P(b); P(c);
P(a + b);
P((c - a)/b);
} ///:~
// An array of struct
typedef
struct {
int i, j, k;
}
ThreeDpoint;
int
main() {
ThreeDpoint p[10];
for(int i =
0; i < 10; i++) {
p[i].i = i + 1;
p[i].j = i + 2;
p[i].k = i + 3;
}
} ///:~
// The size and simple use of a union
#include
<iostream>
using
namespace std;
union
Packed { // Declaration similar to a class
char i;
short j;
int k;
long l;
float f;
double d;
// The union will be
the size of a
// double, since that's the largest element
}; // Semicolon ends a
union, like a struct
int
main() {
cout <<
"sizeof(Packed) = "
<< sizeof(Packed)
<< endl;
Packed x;
x.i = 'c';
cout << x.i
<< endl;
x.d = 3.14159;
cout << x.d
<< endl;
} ///:~
int
main() {
void* vp;
char
c;
int
i;
float f;
double d;
// The address of
ANY type can be
// assigned to a void pointer:
vp = &c;
vp = &i;
vp = &f;
vp = &d;
} ///:~
#include
<iostream>
using
namespace std;
int dog,
cat, bird, fish;
void
f(int pet) {
cout <<
"pet id number: " << pet << endl;
}
int
main() {
int i, j, k;
} ///:~
#include
<iostream>
using
namespace std;
int dog,
cat, bird, fish;
void
f(int pet) {
cout <<
"pet id number: " << pet << endl;
}
int
main() {
int i, j, k;
cout <<
"f(): " << (long)&f << endl;
cout <<
"dog: " << (long)&dog << endl;
cout <<
"cat: " << (long)&cat << endl;
cout <<
"bird: " << (long)&bird << endl;
cout <<
"fish: " << (long)&fish << endl;
cout <<
"i: " << (long)&i << endl;
cout <<
"j: " << (long)&j << endl;
cout <<
"k: " << (long)&k << endl;
} ///:~